using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using GFramework;

public class EditorUtils
{
	#region [ Scenes ]

	/// <summary>
	/// Gets the name of the current scene.
	/// </summary>
	public static string currentSceneName
	{
		get
		{
			string name = EditorApplication.currentScene;
			name = name.Substring(name.LastIndexOf('/') + 1);

			int idx = name.LastIndexOf('.');
			if (idx > 0)
				name = name.Substring(0, idx);
			return name;
		}
	}

	#endregion

	[MenuItem("GFramework/Utilities/Track Script Names")]
	static void UpdateObjectScriptsName()
	{
		GMonoBehaviour[] allObjects = (GMonoBehaviour[])Object.FindObjectsOfType(typeof(GMonoBehaviour));
		foreach (GMonoBehaviour obj in allObjects)
			obj._scriptName = obj.GetType().Name;
	}

	[MenuItem("GFramework/Utilities/Count bone")]
	static void CountBoneSize()
	{
		Object[] allObjects = (Object[])Selection.GetFiltered(typeof(GameObject), SelectionMode.TopLevel);
		foreach (Object obj in allObjects)
		{
			SkinnedMeshRenderer renderer = ((GameObject)obj).GetComponent<SkinnedMeshRenderer>();
			if (renderer != null)
			{
				Debug.Log(renderer.name + " bindpose size " + renderer.sharedMesh.bindposes.Length);
				Debug.Log(renderer.name + " bone size " + renderer.bones.Length);
			}
		}
	}

	#region [ Prefab and Game Object ]

	/// <summary>
	/// If game object is a prefab instance
	/// </summary>
	public static bool IsPrefabInstance(GameObject go)
	{
		if (go == null)
			return false;
		PrefabType prefabType = PrefabUtility.GetPrefabType(go);
		return prefabType == PrefabType.PrefabInstance || prefabType == PrefabType.ModelPrefabInstance; ;
	}

	#endregion

	#region [ Asset Resources ]

	/// <summary>
	/// Get all texture in material
	/// </summary>
	public static Texture[] GetMaterialTextures(Material material)
	{
		if (material == null)
			return new Texture[] { };

		SerializedObject so = new SerializedObject(material);
		SerializedProperty sp = so.FindProperty("m_SavedProperties.m_TexEnvs.Array.size");
		int texCount = sp.intValue;
		if (texCount == 0)
			return new Texture[] { };

		List<Texture> textures = new List<Texture>();
		for (int i = 0; i < texCount; i++)
		{
			sp = so.FindProperty("m_SavedProperties.m_TexEnvs.Array.data[" + i + "].second.m_Texture");
			if (sp.objectReferenceValue != null)
				textures.Add(sp.objectReferenceValue as Texture);
		}

		return textures.ToArray();
	}

	/// <summary>
	/// Set textures to material
	/// </summary>
	public static void SetMaterialTextures(Material material, Texture[] texture)
	{
		if (material == null)
			return;

		SerializedObject so = new SerializedObject(material);
		SerializedProperty sp = so.FindProperty("m_SavedProperties.m_TexEnvs.Array.size");
		int texCount = sp.intValue;
		if (texCount > texture.Length)
			texCount = texture.Length;

		if (texCount == 0)
			return;

		//Texture[] textures = new Texture[texCount];
		for (int i = 0; i < texCount; i++)
		{
			sp = so.FindProperty("m_SavedProperties.m_TexEnvs.Array.data[" + i + "].second.m_Texture");
			sp.objectReferenceValue = texture[i];
		}

		so.ApplyModifiedProperties();
	}

	#endregion

	#region [ Utilities ]

	/// <summary>
	/// Registers the undo.
	/// </summary>
	public static void RegisterUndo(string name, params Object[] objects)
	{
		if (objects != null && objects.Length > 0)
		{
			foreach (Object obj in objects)
			{
				if (obj == null) continue;
				Undo.RegisterUndo(obj, name);
				EditorUtility.SetDirty(obj);
			}
		}
		else
		{
			Undo.RegisterSceneUndo(name);
		}
	}

	[MenuItem("GFramework/Utilities/Show client log")]
	public static void ShowClientLog()
	{
		string dir = Application.dataPath.Replace("Assets", "");
		System.Diagnostics.Process process = new System.Diagnostics.Process();
		process.StartInfo.FileName = dir + "../tools/bin/baretail.exe";
		process.StartInfo.Arguments = dir + "log/xclient.log";
		Debug.Log("Open log file \"" + process.StartInfo.Arguments + "\"");
		process.StartInfo.UseShellExecute = true;
		process.Start();
	}

	//[MenuItem("Utilities/Components/Find Missing Scripts")]
	public static void FindMissingScripts()
	{
		GameObject[] gameObjects = Selection.gameObjects;
		if (gameObjects.Length == 0)
			gameObjects = (GameObject[])Object.FindObjectsOfType(typeof(GameObject));

		bool hasMissingScripts = false;
		foreach (GameObject go in gameObjects)
		{
			Component[] components = go.GetComponents<Component>();
			for (int i = 0; i < components.Length; i++)
			{
				if (components[i] == null)
				{
					hasMissingScripts = true;
					Debug.Log("[" + Utils.GetGameObjectFullName(go) + "] has an empty script attached index: " + i, go);
				}
			}
		}

		if (!hasMissingScripts)
			Debug.Log("No missing scripts!!!");
	}

	#endregion
}